package com.imagecollector.common.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.HttpVersion;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.util.Map;

/**
 * @Author: wrf
 * @Date: 2024/6/28 15:37
 * @Description:
 */
@Slf4j
public class HttpClientUtils {

    private static final PoolingHttpClientConnectionManager connectionManager;
    private static final CloseableHttpClient httpClient;

    static {
        // 初始化连接池管理器
        connectionManager = new PoolingHttpClientConnectionManager();
        // 设置最大连接数
        connectionManager.setMaxTotal(100);
        // 设置每个路由的最大连接数
        connectionManager.setDefaultMaxPerRoute(20);

        // 使用连接池管理器创建HttpClient实例
        httpClient = HttpClients.custom()
                .setConnectionManager(connectionManager)
                .build();
    }

    public static CloseableHttpClient getClient() {
        return httpClient;
    }

    // 如果应用需要关闭时，可以调用此方法释放资源
    public static void shutdown() {
        connectionManager.shutdown();
    }

    /**
     * 向指定URL发送GET请求，并返回响应内容。
     *
     * @param url 发送请求的URL
     * @return 响应内容，若发生错误则返回null或错误信息
     */
    public static String sendGetRequest(String url, Map<String, String> urlParams) throws IOException {
        if (urlParams != null && !urlParams.isEmpty()) {
            StringBuilder paramBuilder = new StringBuilder();
            for (Map.Entry<String, String> entry : urlParams.entrySet()) {
                paramBuilder.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
            }
            // 移除最后一个多余的"&"符号
            url += "?" + paramBuilder.substring(0, paramBuilder.length() - 1);
        }
        CloseableHttpClient httpClient = getClient();
        HttpGet httpGet = new HttpGet(url);
        httpGet.setProtocolVersion(HttpVersion.HTTP_1_1); // 明确设置使用的HTTP协议版本

        CloseableHttpResponse response = httpClient.execute(httpGet);
        HttpEntity entity = response.getEntity();

        // 检查HTTP响应状态码
        if (entity != null && response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
            // 明确指定字符集，避免字符集问题
            return EntityUtils.toString(entity, "UTF-8");
        } else {
            // 如果HTTP状态码不为200，记录日志或返回错误信息
            log.error("HTTP请求失败，状态码：{}", response.getStatusLine().getStatusCode());
            return null;
        }

    }

    /**
     * 向指定URL发送POST请求，并返回响应内容。
     *
     * @param url      发送请求的URL
     * @param postData POST请求的表单数据，格式如："key1=value1&key2=value2"
     * @return 响应内容，若发生错误或HTTP状态码非200则返回null
     */
    public static String sendPostRequest(String url, String postData) throws IOException {
        CloseableHttpClient httpClient = getClient();
        HttpPost httpPost = new HttpPost(url);
        // 设置请求体
        httpPost.setEntity(new StringEntity(postData, "UTF-8"));
        httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded");

        CloseableHttpResponse response = httpClient.execute(httpPost);
        try {
            // 检查HTTP状态码
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode != 200) {
                log.error("POST request failed with status code: " + statusCode);
                return null;
            }
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                return EntityUtils.toString(entity, "UTF-8");
            }
        } finally {
            // 确保响应体也被关闭
            EntityUtils.consume(response.getEntity());
            response.close();
        }
        return null;
    }

}
